using System;
using System.Collections.Generic;
using SimpleCore.DebugTool;

namespace SimpleCore
{
    public abstract class Message
    {
        public static void Add<T>(Action<T> receiver) where T : BaseMessage<T>
        {
            var messageId = GetId<T>();
            if(_map.ContainsKey(messageId))
            {
                var list = _map[messageId];
                var temp = (Action<Message>)receiver;
                if(list.Contains(temp))
                {
                    LogHelper.LogWarning($"Already Contian {receiver}");
                    return;
                }
                list.Add(temp);
            }
            else
            {
                var list = new List<Action<Message>>();
                var temp = (Action<Message>)receiver;
                list.Add(temp);
                _map[messageId] = list;
            }
        }

        public static void Remove<T>(Action<T> receiver)  where T : BaseMessage<T>
        {
            var messageId = GetId<T>();
            if(_map.ContainsKey(messageId))
            {
                var list = _map[messageId];
                list.Remove((Action<Message>)receiver);

                if(list.Count <= 0)
                {
                    _map.Remove(messageId);
                }
            }
        }

        public static void Clear<T>() where T : BaseMessage<T>
        {
            var messageId = GetId<T>();
            _map.Remove(messageId);
        }

        public static void Trigger<T>(T message = default) where T : BaseMessage<T>
        {
            var messageId = GetId<T>();
            if(_map.ContainsKey(messageId))
            {
                var list = _map[messageId];
                for (int i = 0; i < list.Count;i++)
                {
                    var temp = (Action<T>)list[i];
                    temp.Invoke(message);
                }
            }
        }

        static int GetId<T>() where T : BaseMessage<T>
        {
            return typeof(T).GetHashCode();
        }

        static Dictionary<int, List<Action<Message>>> _map = new Dictionary<int, List<Action<Message>>>();
    }
}
